/**
 * @file doubleLinkList.c
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2024-10-25
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "doubleLinkList.h"


static void *memeryMalloc(int size)
{
	return malloc((size_t)size);
}

static void memeryFree(void *addr)
{
	free(addr);
}


static doubleLinkListNode_t *mallocLinkListNode(int data)
{
	doubleLinkListNode_t *node_new = NULL;

	node_new = (doubleLinkListNode_t *)memeryMalloc(sizeof(doubleLinkListNode_t));
	if(node_new != NULL)
	{
		node_new->next = NULL;
		node_new->prev = NULL;
		node_new->data = data;
	}

	return node_new;
}

doubleLinkListNode_t *findLinkListLastNode(doubleLinkListNode_t *head)
{
	doubleLinkListNode_t *node_p = head;

	if(node_p == NULL)
	{
		return NULL;
	}

	while(node_p->next != NULL)
	{
		node_p = node_p->next;
	}

	return node_p;
}

doubleLinkListNode_t *findLinkListNode(doubleLinkListNode_t *head,int assign)
{
	doubleLinkListNode_t *node_p = head;

    while(node_p != NULL)
    {
        if(node_p->data == assign)
        {
            break;
        }
        node_p = node_p->next;
    }
    return node_p;
}

int appendNodeToHeadBehind(doubleLinkListNode_t **head,int data)
{
	doubleLinkListNode_t *node_new = NULL;
	doubleLinkListNode_t *node_p = *head;

	node_new = mallocLinkListNode(data);

	if(node_new == NULL)
	{
		return -1;
	}

	if(node_p == NULL)
	{
		*head = node_new;
	}
	else
	{
		node_p->prev = node_new;
		node_new->next = node_p;
		*head = node_new;
	}

	return 0;
}

int appendNodeToHeadBefore(doubleLinkListNode_t **head,int data)
{
	doubleLinkListNode_t *node_new = NULL;
	doubleLinkListNode_t *node_p = *head;

	node_new = mallocLinkListNode(data);

	if(node_new == NULL)
	{
		return -1;
	}

	if(node_p == NULL)
	{
		*head = node_new;
	}
	else
	{
		if(node_p->next != NULL)
		{
			node_p->next->prev = node_new;
		}
		node_new->next = node_p->next;
		node_new->prev = node_p;
		node_p->next = node_new;
	}

	return 0;
}


int appendNodeToTail(doubleLinkListNode_t **head,int data)
{
	doubleLinkListNode_t *node_new = NULL;
	doubleLinkListNode_t *node_p = *head;

	node_new = mallocLinkListNode(data);

	if(node_new == NULL)
	{
		return -1;
	}

	if(node_p == NULL)
	{
		*head = node_new;
	}
	else
	{
		node_p = findLinkListLastNode(node_p);
		node_new->prev = node_p;
		node_p->next = node_new;
	}

	return 0;
}

int appendNodeToAssign(doubleLinkListNode_t **head,int assign,int data)
{
	doubleLinkListNode_t *node_new = NULL;
	doubleLinkListNode_t *node_p = *head;

	node_p = findLinkListNode(node_p,assign);
	if(node_p == NULL)
	{
		return -1;
	}

	node_new = mallocLinkListNode(data);
	if(node_new == NULL)
	{
		return -2;
	}

	if(node_p->next != NULL)
	{
		node_p->next->prev = node_new;
		node_new->next = node_p->next;
		node_p->next = node_new;
		node_new->prev = node_p;
	}
	else
	{
		node_p->next = node_new;
		node_new->prev = node_p;
	}

	return 0;
}

int removeHeadNode(doubleLinkListNode_t **head)
{
	doubleLinkListNode_t *node_p = *head;

	if(node_p == NULL)
	{
		return -1;
	}

	if(node_p->next != NULL)
	{
		node_p->next->prev = NULL;
		*head = node_p->next;
	}
	else
	{
		*head = NULL;
	}
	memeryFree(node_p);

	return 0;
}

int removeTailNode(doubleLinkListNode_t **head)
{
	doubleLinkListNode_t *node_p = *head;

	if(node_p == NULL)
	{
		return -1;
	}

	if(node_p->next != NULL)
	{
		node_p = findLinkListLastNode(node_p);
		if(node_p == NULL)
		{
			return -2;
		}
		node_p->prev->next = node_p->next;
		node_p->prev = NULL;
	}
	else
	{
		*head = NULL;
	}
	
	memeryFree(node_p);

	return 0;
}	

int removeAssignNode(doubleLinkListNode_t **head,int assign)
{
	doubleLinkListNode_t *node_p = *head;

	if(node_p == NULL)
	{
		return -1;
	}

	node_p = findLinkListNode(node_p,assign);
	if(node_p == NULL)
	{
		return -2;
	}

	if(*head == node_p)
	{
		*head = node_p->next;
	}
	if(node_p->next)
	{
		node_p->next->prev = node_p->prev;
	}
	if(node_p->prev)
	{
		node_p->prev->next = node_p->next;
	}

	memeryFree(node_p);

	return 0;
}

int modifiedAssignNode(doubleLinkListNode_t *head,int assign,int data)
{
	doubleLinkListNode_t *node_p = head;

	if(node_p == NULL)
	{
		return -1;
	}

	node_p = findLinkListNode(node_p,assign);
	if(node_p == NULL)
	{
		return -2;
	}
	node_p->data = data;

	return 0;
}

void printLinkListNode(doubleLinkListNode_t *head)
{
	doubleLinkListNode_t *node_p = head;

	if(node_p == NULL)
	{
		printf("head node is NULL\n");
		return;
	}
	// node_p = findLinkListLastNode(node_p);
	while(node_p != NULL)
    {
        printf("%d ", node_p->data);
        // node_p = node_p->prev;
		node_p = node_p->next;
    }
    printf("\n");
}